<!-- 聊天室页面 -->
<template>
  <div class="shell">
    <!-- 模型选择区域 -->
    <div class="model-selector">
      <div
        v-for="model in assistants"
        :key="model"
        class="model-option"
        :class="{ active: currentAss === model }"
        @click="selectModel(model)">
        {{ descriAss[model] }}
      </div>
      <div class="clear-txt" @click="clearHistoryMsg">清空对话</div>
    </div>
    <div class="content" ref="chatContent" @scroll="handleScroll">
      <!-- 聊天内容区域 -->
      <div v-for="(message, index) in messages" :key="index" class="message" :class="message.role">
        <div v-if="message.thinking" class="thinking-content">
          <div class="thinking-title">思考过程:</div>
          <div v-html="marked.parse(message.thinking)"></div>
        </div>
        <!-- 添加加载动画 -->
        <div v-if="message.role === 'message-ai' && message.content === '' && isLoading" class="loading-animation">
          <div class="dot"></div>
          <div class="dot"></div>
          <div class="dot"></div>
        </div>
        <!-- 最新回答 -->
        <div class="message-content">
          <div v-html="marked.parse(message.content)"></div>
          <div style="position: relative;right: 0;" v-if="message.role === 'message-ai' && !isLoading && isResponding && index === messages.length - 1" class="loading-animation">
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
          </div>
        </div>
      </div>
    </div>
    <div class="input-content">
      <textarea
        v-model="userInput"
        placeholder="请输入您的问题..."
        @keydown.enter.prevent="sendMessage"
        :disabled="isResponding"
      ></textarea>
      <button @click="sendMessage" :disabled="isResponding">发送</button>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, inject } from 'vue'
import { marked } from 'marked'
import { ElMessageBox } from 'element-plus'

// 使用 inject 获取全局提供的 axios 实例
const $axios = inject('$axios')
const $tools = inject('$tools')
// API基础URL
// const API_BASE_URL = "http://localhost:8080"
const API_BASE_URL = "http://159.75.133.177:8080"


// 响应式数据
const chatContent = ref(null)
const userInput = ref('')
// 农业咨询历史记录
const messageHistory = ref([])
const messages = ref([])

// 添加自动滚动标志
const shouldAutoScroll = ref(true)

// 监听滚动事件
const handleScroll = () => {
  if (!chatContent.value) return
  const { scrollTop, scrollHeight, clientHeight } = chatContent.value
  // 判断是否滚动到底部（允许1px的误差）
  shouldAutoScroll.value = Math.abs(scrollHeight - scrollTop - clientHeight) <= 1
}

// 滚动到底部的方法
const scrollToBottom = () => {
  if (chatContent.value && shouldAutoScroll.value) {
    chatContent.value.scrollTop = chatContent.value.scrollHeight
  }
}

// 添加消息到界面
const addMessage = (content, role = 'message-user', thinking = '') => {
  messages.value.push({
    content,
    role,
    thinking
  })
  // 等待DOM更新后滚动到底部
  setTimeout(() => {
    scrollToBottom()
  }, 0)
}

// 添加加载状态变量
const isLoading = ref(false)
// 添加响应状态变量
const isResponding = ref(false)
const assistants = ['agri-expert', 'agri-data']
const descriAss = {"agri-expert":"农业咨询", "agri-data":"数据查询"}
const currentAss = ref('agri-expert')
const greet = {
  "agri-expert": "你好！我是你的农业专家助手。我可以帮助你解答关于种植、养殖、土壤管理、病虫害防治等各种农业问题。无论是你想知道如何提高作物产量，还是想了解如何防治病虫害，我都可以提供实用的建议和指导。你可以随时向我提问，我会用简单易懂的语言为你解答。",
  "agri-data": "您好！我是农产品数据咨询客服，专门为您提供关于农产品的相关数据和信息。无论您想了解农产品的价格走势、市场需求、供应情况，还是其他与农产品相关的数据，我都能为您提供准确、及时的解答和帮助。我的目标是帮助您更好地理解农产品市场，为您的决策提供数据支持。请问您有什么具体问题或需要了解的信息吗？"
}


// 现在默认是v3
const currentModel = ref('deepseek-v3')
const models = ['deepseek-v3', 'deepseek-r1']

// 清空对话
const clearChat = () => {
  messages.value = []
  messageHistory.value = []
  
}

// 选择模型，农业咨询/数据查询
const selectModel = async (model) => {
  if(model === currentAss.value || isResponding.value) {
    return
  }
  currentAss.value = model
  clearChat()
  await getHistoryMsg()
  renderMsg(messageHistory,model)
  // console.log(`已切换到模型: ${model}`)
}

// 更新界面显示的消息
const renderMsg = (msgHistory,type) => {
  messages.value = []
  // console.log(msgHistory.value)
  // 添加提示
  addMessage(greet[type],"message-ai");
  for (const msg of msgHistory.value) {
    addMessage(msg.content, msg.role === 'user' ? 'message-user' : 'message-ai')
  }
}

const clearHistoryMsg = async () => {
  // 弹出确认框，询问用户是否确认清除当前助手类型的聊天记录
  const confirmMessage = `是否清除${descriAss[currentAss.value]}的聊天记录？`
  
  try {
    // 使用Element Plus的确认对话框
    await ElMessageBox.confirm(
      confirmMessage,
      '提示',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
        customStyle: { marginTop: '-300px' }
      }
    )
    
    // 用户点击确认后执行
    // 使用$axios发送DELETE请求到后端API
    const response = await $axios.delete(`/ai/chat/history`, {
      data: {
        type: currentAss.value
      }
    })
    
    // 清空本地消息
    clearChat()
    
    // 添加提示消息
    addMessage(greet[currentAss.value], 'message-ai')
    
    console.log('历史记录已清空')
  } catch (error) {
    if (error !== 'cancel') {
      console.error('清空历史记录失败:', error.response?.data || error.message)
      // 可以在这里添加用户提示
    }
    // 用户取消操作，不做任何处理
  }
}

// 获得历史记录
const getHistoryMsg = async () => {
  try {
    // 使用$axios发送GET请求，将type参数作为查询参数
    const response = await $axios.get(`/ai/chat/history`, {
      params: {
        type: currentAss.value
      }
    })
    
    // 获取响应数据
    const data = response.data
    // console.log(data)
    // 过滤掉系统消息，只保留用户和助手的消息
    messageHistory.value = data.filter(msg => msg.role !== 'system')
    // 更新界面显示的消息
    renderMsg(messageHistory,currentAss.value)
    
    return data
  } catch (error) {
    console.error('获取历史消息失败:', error.response?.data || error.message)
    return []
  }
}

// 发送消息
const sendMessage = async () => {
  const message = userInput.value.trim()
  if (!message || isResponding.value) return

  // 设置响应状态为true
  isResponding.value = true
  // 添加用户消息
  addMessage(message)
  userInput.value = ''

  // 添加用户消息到历史记录
  messageHistory.value.push({
    role: "user",
    content: message
  })

  try {
    // 创建AI消息占位
    let fullResponse = ''
    let fullThinking = ''
    addMessage('', 'message-ai')
    // 设置加载状态为true
    isLoading.value = true
    // 使用fetch发送POST请求
    const response = await fetch(`${API_BASE_URL}/ai/chat/stream`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `${localStorage.getItem('token')}`
      },
      body: JSON.stringify({
        messages: [...messageHistory.value],
        model: currentModel.value,
        type: currentAss.value,
      })
    })

    // 获取响应的ReadableStream
    const reader = response.body.getReader()
    const decoder = new TextDecoder()

    while (true) {
      const { done, value } = await reader.read()
      if (done) break

      const chunk = decoder.decode(value)
      const lines = chunk.split('\n')

      for (const line of lines) {
        if (line.startsWith('data: ')) {
          const jsonStr = line.slice(6)
          if (jsonStr.trim() && jsonStr !== '[DONE]') {
            try {
              const jsonData = JSON.parse(jsonStr)
              if (jsonData.choices && jsonData.choices[0].delta) {
                // 处理思考内容
                if (currentModel.value === "deepseek-r1" && 
                    jsonData.choices[0].delta.reasoning_content) {
                  fullThinking += jsonData.choices[0].delta.reasoning_content
                  messages.value[messages.value.length - 1].thinking = fullThinking
                }

                // 处理回复内容
                if (jsonData.choices[0].delta.content) {
                  // 收到第一个响应时，关闭加载动画
                  if (fullResponse === '') {
                    isLoading.value = false
                  }
                  fullResponse += jsonData.choices[0].delta.content
                  messages.value[messages.value.length - 1].content = fullResponse
                  if(shouldAutoScroll.value) {
                    scrollToBottom()
                  }
                }
              }
            } catch (e) {
              console.error('解析JSON失败:', e)
            }
          }
        }
      }
    }

    // 确保加载状态关闭
    isLoading.value = false

    // 将AI回复添加到历史记录
    messageHistory.value.push({
      role: "assistant",
      content: fullResponse
    })

    // 如果历史记录过长，进行裁剪
    if (messageHistory.value.length > 10) {
      messageHistory.value = messageHistory.value.slice(messageHistory.value.length - 10)
    }

  } catch (error) {
    console.error('请求失败:', error)
    messages.value[messages.value.length - 1].content = '抱歉，发生了错误: ' + error.message
  } finally {
    // 无论成功还是失败，都将响应状态设置为false
    isResponding.value = false
  }
}
// 在组件挂载时获取历史记录
onMounted(() => {
  getHistoryMsg()
})
</script>

<style lang="less" scoped>
.shell {
  width: 1100px;
  height: 800px;
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  margin-top: 20px;
  .content {
    flex: 1;
    padding: 20px;
    overflow-y: auto;

    &::-webkit-scrollbar {
      width: 8px;
    }

    &::-webkit-scrollbar-track {
      background: #f1f1f1;
      border-radius: 10px;
    }

    &::-webkit-scrollbar-thumb {
      background: #c1c1c1;
      border-radius: 10px;

      &:hover {
        background: #a8a8a8;
      }
    }
  }

  .input-content {
    height: 120px;
    border-top: 1px solid #eee;
    display: flex;
    padding: 10px;
    align-items: center;

    textarea {
      flex: 1;
      resize: none;
      border: none;
      height: 100%;
      border-radius: 5px;
      padding: 10px;
      font-size: 14px;
      background-color: #f9f9f9;
      outline: none;
      box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.1);

      &::-webkit-scrollbar {
        width: 8px;
      }

      &::-webkit-scrollbar-track {
        background: #f1f1f1;
        border-radius: 10px;
      }

      &::-webkit-scrollbar-thumb {
        background: #c1c1c1;
        border-radius: 10px;

        &:hover {
          background: #a8a8a8;
        }
      }
    }

    button {
      width: 120px;
      height: 50px;
      margin-left: 10px;
      border: none;
      background-color: #319A19;
      color: white;
      border-radius: 5px;
      cursor: pointer;
      transition: background-color 0.3s;

      &:hover {
        background-color: #46d426;
      }
    }
  }
}

/* 模型选择区域样式 */
.model-selector {
  display: flex;
  padding: 10px;
  background-color: #f9f9f9;
  border-bottom: 1px solid #eee;

  .model-option {
    padding: 8px 15px;
    margin-right: 10px;
    border-radius: 5px;
    cursor: pointer;
    border: 1px solid #ddd;
    transition: all 0.3s;

    &.active {
      background-color: #319A19;
      color: white;
      border-color: #319A19;
    }
  }
}

/* 清空对话按钮 */
.clear-txt {
  font-size: 14px;
  color: #666;
  margin-left: auto;
  padding: 0px 15px;
  margin-right: 10px;
  border-radius: 5px;
  cursor: pointer;
  border: 1px solid #ddd;
  line-height: 40px;
  transition: all 0.3s;

  &:hover {
    background-color: #e43a3a;
    color: white;
    border-color: #e43a3a;
  }
}

/* 消息样式 */
.message {
  margin-bottom: 25px;
  display: flex;

  &.message-user {
    justify-content: flex-end;

    .message-content {
      background-color: #1890ff;
      color: white;
      border-bottom-right-radius: 5px;
    }
  }

  &.message-ai {
    justify-content: flex-start;
    flex-direction: column;

    .message-content {
      background-color: #f9f9f9;
      box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
      color: #333;
      border-bottom-left-radius: 5px;
    }
  }

  .message-content {
    max-width: 86%;
    padding: 15px 20px;
    border-radius: 10px;
    font-size: 14px;
    line-height: 1.5;

    // markdown格式
    :deep(pre) {
      background-color: #f6f8fa;
      padding: 16px;
      border-radius: 6px;
      overflow-x: auto;
      margin: 10px 0;
      border: 1px solid #e1e4e8;
    }

    :deep(code) {
      font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
      font-size: 13px;
      tab-size: 4;
    }

    :deep(:not(pre) > code) {
      background-color: rgba(175, 184, 193, 0.2);
      padding: 0.2em 0.4em;
      border-radius: 3px;
      font-size: 85%;
    }

    :deep(p) {
      margin-bottom: 2px;
    }

    :deep(ul), :deep(ol) {
      margin-left: 20px;
      margin-bottom: 10px;
    }

    :deep(img) {
      max-width: 100%;
      border-radius: 5px;
      margin: 5px 0;
    }

    :deep(table) {
      border-collapse: collapse;
      width: 100%;
      margin: 10px 0;
      display: block;
      overflow-x: auto;
      white-space: nowrap;

      th, td {
        border: 1px solid #ddd;
        padding: 8px;
        text-align: left;
      }

      th {
        background-color: #f2f2f2;
      }
    }

    :deep(blockquote) {
      border-left: 4px solid #ddd;
      padding-left: 10px;
      color: #666;
      margin: 10px 0;
    }
  }
}

/* 思考内容样式 */
.thinking-content {
  background-color: #f8f9fa;
  border-left: 3px solid #6c757d;
  padding: 10px 15px;
  margin-bottom: 10px;
  font-size: 13px;
  color: #555;
  border-radius: 5px;
  max-width: 70%;

  .thinking-title {
    font-weight: bold;
    margin-bottom: 5px;
    color: #333;
  }
}
/* 加载动画样式 */
.loading-animation {
  display: flex;
  // align-items: center;
  // justify-content: center;
  padding: 10px;
  
  .dot {
    width: 8px;
    height: 8px;
    background-color: #319A19;
    border-radius: 50%;
    margin: 0 4px;
    animation: bounce 1.4s infinite ease-in-out both;
    
    &:nth-child(1) {
      animation-delay: -0.32s;
    }
    
    &:nth-child(2) {
      animation-delay: -0.16s;
    }
  }
}

@keyframes bounce {
  0%, 80%, 100% {
    transform: scale(0);
  }
  40% {
    transform: scale(1);
  }
}
</style>